// A lightweight string wrapper.  Can be implicitly constructed from a
// "const char*" or a "std::string".
//
// Effective use can help avoid conversions from "const char*" to
// "std::string" and back again.  Functions and methods can accept a
// "const StringWrapper&" as a parameter, and then callers can pass either
// string representation.

#ifndef BASE_STRING_WRAPPER
#define BASE_STRING_WRAPPER

#include <assert.h>
#include <string.h>
#include <cstddef>
#include <string>

#include "base/types.h"

namespace base {

class StringWrapper {
public:
    // Implicit type conversions are what we want here.
    StringWrapper(const char* string)
            : string_(string), length_(static_cast<int>(strlen(string))) {}
    StringWrapper(const std::string& string)
            : string_(string.c_str()), length_(static_cast<int>(string.length())) {}

    inline const char* GetString() const { return string_; }
    inline int GetLength() const { return length_; }

    char operator[](std::ptrdiff_t index) const {
        assert(index >= 0);
        assert(string_ != NULL);
        return string_[index];
    }

private:
    const char* string_;
    int length_;

    DISALLOW_IMPLICIT_CONSTRUCTORS(StringWrapper);
};

inline bool operator==(const StringWrapper& a, const StringWrapper& b) {
    if (a.GetString() == b.GetString())
        return true;
    if (a.GetLength() != b.GetLength())
        return false;
    return strcmp(a.GetString(), b.GetString()) == 0;
}

inline bool operator!=(const StringWrapper& a, const StringWrapper& b) {
    return !(a == b);
}

inline bool operator<(const StringWrapper& a, const StringWrapper& b) {
    return strcmp(a.GetString(), b.GetString()) < 0;
}

inline bool operator<=(const StringWrapper& a, const StringWrapper& b) {
    return strcmp(a.GetString(), b.GetString()) <= 0;
}

inline bool operator>(const StringWrapper& a, const StringWrapper& b) {
    return strcmp(a.GetString(), b.GetString()) > 0;
}

inline bool operator>=(const StringWrapper& a, const StringWrapper& b) {
    return strcmp(a.GetString(), b.GetString()) >= 0;
}

} // namespace base

#endif // BASE_STRING_WRAPPER